﻿using Infrastructure.Model.DI;
using Microsoft.Extensions.Logging;
using Model.EntityModel.Auth;
using Model.EntityModel.SysModel;
using Repository.IRepository.ISysRepository;
using SqlSugar;

namespace Repository.Repository.SysRepository
{
    /// <summary>
    /// 部门
    /// </summary>
    [AppService(ServiceType = typeof(IDeptRepository), ServiceLifetime = LifeTime.Transient)]
    public class DeptRepository : SqlSugarBaseRepository<Dept>, IDeptRepository
    {
        private readonly ILogger<DeptRepository> _logger;

        public DeptRepository(ILogger<DeptRepository> logger)
        {
            _logger = logger;
        }

        public async Task<string> CreateDeptAsync(Dept dept)
        {
            try
            {
                dept.Id = Guid.NewGuid().ToString();
                var result = await _db.Insertable(dept).ExecuteReturnEntityAsync();
                return result?.Id;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"创建部门失败: {dept.Name}");
                throw;
            }
        }
        /// <summary>
        /// 获取部门树结构
        /// </summary>
        /// <returns>部门树</returns>
        public List<Dept> GetDeptTree()
        {
            try
            {
                // 获取所有部门数据
                var allDepts = _db.Queryable<Dept>().ToList();

                // 初始化每个部门的子部门集合
                foreach (var dept in allDepts)
                {
                    dept.Children = new List<Dept>();
                }

                // 创建部门ID索引字典
                var deptDict = allDepts.ToDictionary(d => d.Id, d => d);

                // 构建父子关系
                foreach (var dept in allDepts)
                {
                    if (string.IsNullOrEmpty(dept.ParentId)) continue;

                    if (deptDict.TryGetValue(dept.ParentId, out var parent))
                    {
                        parent.Children.Add(dept);  // 将当前部门加入父部门的子集
                    }
                    else
                    {
                        // 日志记录无效的父部门关联
                        _logger.LogWarning($"未找到ParentId={dept.ParentId}的部门，子部门{dept.Id}未能关联");
                    }
                }

                // 提取顶级部门（无父部门）
                return allDepts.Where(d => string.IsNullOrEmpty(d.ParentId)).ToList();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取部门树结构失败");
                throw;
            }
        }
        public async Task<bool> UpdateDeptAsync(Dept dept)
        {
            try
            {
                return await _db.Updateable(dept)
                    .IgnoreColumns(ignoreAllNullColumns: true)
                    .ExecuteCommandAsync() > 0;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"更新部门失败: {dept.Id}");
                throw;
            }
        }

        public async Task<bool> DeleteDeptAsync(string id)
        {
            try
            {
                return await _db.Deleteable<Dept>()
                    .Where(d => d.Id == id)
                    .ExecuteCommandAsync() > 0;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"删除部门失败: {id}");
                throw;
            }
        }

        public async Task<Dept> GetDeptByIdAsync(string id)
        {
            try
            {
                return await _db.Queryable<Dept>()
                    .Where(d => d.Id == id)
                    .FirstAsync();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取部门信息失败: {id}");
                throw;
            }
        }

        public async Task<List<Dept>> GetAllDeptsAsync()
        {
            try
            {
                return await _db.Queryable<Dept>().ToListAsync();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取所有部门失败");
                throw;
            }
        }

        public async Task<bool> IsDeptExistsAsync(string deptId)
        {
            try
            {
                return await _db.Queryable<Dept>()
                    .Where(d => d.Id == deptId)
                    .AnyAsync();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"检查部门存在性失败: {deptId}");
                throw;
            }
        }
        public async Task<List<Dept>> GetDeptHierarchyAsync()
        {
            try
            {
                // 获取所有部门
                var allDepts = await _db.Queryable<Dept>().ToListAsync();

                // 构建部门树
                var hierarchy = allDepts
                    .Where(d => d.ParentId == null)
                    .Select(d => BuildDeptTree(d, allDepts))
                    .ToList();

                return hierarchy;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取部门层级结构失败");
                throw;
            }
        }

        private Dept BuildDeptTree(Dept parent, List<Dept> allDepts)
        {
            parent.Children = allDepts
                .Where(d => d.ParentId == parent.Id)
                .Select(d => BuildDeptTree(d, allDepts))
                .OrderBy(d => d.Name)
                .ToList();

            return parent;
        }

        public List<Dept> GetDeptHierarchy()
        {
            try
            {
                // 获取所有部门
                var allDepts = _db.Queryable<Dept>().ToList();

                // 构建部门树
                var hierarchy = allDepts
                    .Where(d => string.IsNullOrEmpty(d.ParentId))
                    .Select(d => BuildDeptTree(d, allDepts))
                    .ToList();

                return hierarchy;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取部门层级结构失败");
                throw;
            }
        }

        public bool CreateDept(Dept dept)
        {
            try
            {
                dept.Id = Guid.NewGuid().ToString();
                return _db.Insertable(dept).ExecuteCommand() > 0;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"创建部门失败: {dept.Name}");
                throw;
            }
        }

        public bool UpdateDept(Dept dept)
        {
            try
            {
                return _db.Updateable(dept)
                    .IgnoreColumns(ignoreAllNullColumns: true)
                    .ExecuteCommand() > 0;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"更新部门失败: {dept.Id}");
                throw;
            }
        }

        public bool DeptExists(string deptId)
        {
            try
            {
                return _db.Queryable<Dept>()
                    .Where(d => d.Id == deptId)
                    .Any();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"检查部门存在性失败: {deptId}");
                throw;
            }
        }

        public Dept GetDeptById(string deptId)
        {
            try
            {
                return _db.Queryable<Dept>()
                    .Where(d => d.Id == deptId)
                    .First();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取部门信息失败: {deptId}");
                throw;
            }
        }

        public bool DeleteDept(string deptId)
        {
            try
            {
                return _db.Deleteable<Dept>()
                    .Where(d => d.Id == deptId)
                    .ExecuteCommand() > 0;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"删除部门失败: {deptId}");
                throw;
            }
        }

        public List<Dept> GetAllDepts()
        {
            try
            {
                return _db.Queryable<Dept>().ToList();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取所有部门失败");
                throw;
            }
        }
    }
}